//
//  MPBNetWorkBase.h
//  MiaoPai
//
//  Created by jiaxuzhou on 2017/5/24.
//  Copyright © 2017年 jiaxuzhou. All rights reserved.
//

#import "MPBNetWorkBase.h"
#import "MPCURLSessionTask+MPCNetWork.h"
#import "MPBNetWorking.h"
#import <objc/runtime.h>

static AFHTTPSessionManager *httpMrgStatic = nil;

/// 存放所有网络请求对象
static NSMutableArray *maryRequestTasks;


@interface MPBNetWorkBase ()

/// AFNetWorking 网络请求工具
@property (nonatomic, strong)   AFHTTPSessionManager    *httpMrg;

/// 业务请求地址，从子类重写中获得，优先级低于直接传入
@property (nonatomic, copy)     NSString                *strURL;

/// 业务请求参数，从子类重写中获得，优先级低于直接传入
@property (nonatomic, strong)   NSDictionary            *dictParams;

/// 请求参数数组，包含内置参数 上传文件使用
@property (nonatomic, strong)   NSMutableDictionary     *mdictParams2Send;

/// 请求头部外边传入的公共参数
@property (nonatomic, strong)   NSDictionary            *dicParamCommonHeader;

/// 请求body中传入的公共参数
@property (nonatomic, strong)   NSDictionary            *dicParamCommonBody;

/// 超时时间
@property (nonatomic, assign)   NSTimeInterval          timeoutInterval;

/// response类型
@property (nonatomic, assign)   MPE_NetResponseType     enumResponseType;


@end


@implementation MPBNetWorkBase

- (instancetype)init
{
    SEL selector = NSSelectorFromString(MPDNetWorkBaseGetSubClassSel);
    
    if ([self respondsToSelector:selector])
    {
        SuppressPerformSelectorLeakWarning
        (
         Class class = [self performSelector:selector];
         object_setClass(self, class);
         
         );
    }
    
    return [self initWithSessionConfiguration:nil];
}

- (instancetype)initWithApi:(BOOL)isOld
{
    SEL selector = NSSelectorFromString(MPDNetWorkBaseGetSubClassSel);
    
    self.oldApi = isOld;
    if ([self respondsToSelector:selector])
    {
        SuppressPerformSelectorLeakWarning
        (
         Class class = [self performSelector:selector];
         object_setClass(self, class);
         
         );
    }
    
    return [self initWithSessionConfiguration:nil];
}

- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration
{
    if (self = [super init])
    {
        _enumResponseType = MPE_NetResponseType_Json;
        _responseSecType = MPE_NetRespSecType_Json;
        
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^
                      {
                          if (configuration)
                          {
                              
                              httpMrgStatic = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:configuration];
                          }
                          else
                          {
                              httpMrgStatic = [AFHTTPSessionManager manager];
                          }
                          
                          SEL selector = NSSelectorFromString(MPDNetWorkingGetSubClassSel);
                          
                          if ([self respondsToSelector:selector])
                          {
                              SuppressPerformSelectorLeakWarning
                              (
                               Class class = [self performSelector:selector];
                               object_setClass(httpMrgStatic, class);
                               
                               );
                          }
                          
                          httpMrgStatic.requestSerializer.timeoutInterval = MPDefaultRequestTimeoutInterval;
                          [httpMrgStatic.requestSerializer setValue:@"application/x-www-form-urlencoded"  forHTTPHeaderField:@"Content-Type"];


                          httpMrgStatic.responseSerializer = [self getResponseSerializerWithResponseType:_enumResponseType];
                          
                          _httpMrg = httpMrgStatic;
                          
                          /**
                           *   设置固定的请求头
                           */
                          [self setStatiCcommentHTTPHeaders];
                      });
        
        _httpMrg = httpMrgStatic;
    }
    
    return self;
}

- (void)setSessionManager:(AFHTTPSessionManager *)manager
{
    _httpMrg = manager;
}

+ (void)cancelAllRequest
{
    /// 添加锁
    @synchronized(self) {
        [[self allTasks] enumerateObjectsUsingBlock:^(MPURLSessionTask * _Nonnull task, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([task isKindOfClass:[MPURLSessionTask class]]) {
                [(MPURLSessionTask *)task setIsCancel:YES];
                [task cancel];
            }
        }];
        
        [[self allTasks] removeAllObjects];
    };
}

/// 删除最近发送的符合条件的网络请求
+ (void)cancelRequestWithURL:(NSString *)url
{
    if (url == nil) {
        return;
    }
    
    @synchronized(self) {
        [[self allTasks] enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(MPURLSessionTask * _Nonnull task, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([task isKindOfClass:[MPURLSessionTask class]]
                && [task.currentRequest.URL.absoluteString hasSuffix:url]) {
                [(MPURLSessionTask *)task setIsCancel:YES];
                [task cancel];
                [[self allTasks] removeObject:task];
                return;
            }
        }];
    };
}

+ (NSUInteger)tasksCount
{
    return [self allTasks].count;
}

+ (NSMutableArray *)allTasks
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^
                  {
                      if (maryRequestTasks == nil)
                      {
                          maryRequestTasks = [[NSMutableArray alloc] init];
                      }
                  });
    
    return maryRequestTasks;
}

- (AFHTTPSessionManager *)getHttpSessionManager
{
    return _httpMrg;
}



/***************************************************************************************************
 *  异步请求
 ***************************************************************************************************/

- (MPURLSessionTask *)GET:(NSString *)URLString
               parameters:(id)parameters
         isShowNoNetAlert:(BOOL)isShowNoNetAlert
                isEncrypt:(BOOL)isEncrypt
                 priority:(MPE_NetWorkPriority)priority
                  success:(void (^)(MPURLSessionTask *operation, id responseObject))success
                  failure:(void (^)(MPURLSessionTask *operation, NSError *error))failure
                   cached:(void (^)(NSDictionary *cachedObject))cached
{
    return [self __get:URLString
            parameters:parameters
      isShowNoNetAlert:isShowNoNetAlert
             isEncrypt:isEncrypt
              priority:priority
               success:success
               failure:failure
             noNetWork:nil
                cached:cached];
}

- (MPURLSessionTask *)GET:(NSString *)URLString
               parameters:(id)parameters
         isShowNoNetAlert:(BOOL)isShowNoNetAlert
                isEncrypt:(BOOL)isEncrypt
                 priority:(MPE_NetWorkPriority)priority
                  success:(void (^)(MPURLSessionTask *operation, id responseObject))success
                  failure:(void (^)(MPURLSessionTask *operation, NSError *error))failure
                noNetWork:(MPHNoNetWorkBaseBlock)noNetWork
                   cached:(void (^)(NSDictionary *cachedObject))cached
{
    return [self __get:URLString
            parameters:parameters
      isShowNoNetAlert:isShowNoNetAlert
             isEncrypt:isEncrypt
              priority:priority
               success:success
               failure:failure
             noNetWork:noNetWork
                cached:cached];
}

- (MPURLSessionTask *)POST:(NSString *)URLString
                parameters:(id)parameters
          isShowNoNetAlert:(BOOL)isShowNoNetAlert
                 isEncrypt:(BOOL)isEncrypt
                  priority:(MPE_NetWorkPriority)priority
                   success:(void (^)(MPURLSessionTask *operation, id responseObject))success
                   failure:(void (^)(MPURLSessionTask *operation, NSError *error))failure
                    cached:(void (^)(NSDictionary *cachedObject))cached
{
    return [self __post:URLString
             parameters:parameters
       isShowNoNetAlert:isShowNoNetAlert
              isEncrypt:isEncrypt
               priority:priority
                success:success
                failure:failure
              noNetWork:nil
                 cached:cached];
}

- (MPURLSessionTask *)POST:(NSString *)URLString
                parameters:(id)parameters
          isShowNoNetAlert:(BOOL)isShowNoNetAlert
                 isEncrypt:(BOOL)isEncrypt
                  priority:(MPE_NetWorkPriority)priority
                   success:(void (^)(MPURLSessionTask *operation, id responseObject))success
                   failure:(void (^)(MPURLSessionTask *operation, NSError *error))failure
                 noNetWork:(MPHNoNetWorkBaseBlock)noNetWork
                    cached:(void (^)(NSDictionary *cachedObject))cached
{
    return [self __post:URLString
             parameters:parameters
       isShowNoNetAlert:isShowNoNetAlert
              isEncrypt:isEncrypt
               priority:priority
                success:success
                failure:failure
              noNetWork:noNetWork
                 cached:cached];
}


- (MPURLSessionTask *)__get:(NSString *)URLString
                 parameters:(id)parameters
           isShowNoNetAlert:(BOOL)isShowNoNetAlert
                  isEncrypt:(BOOL)isEncrypt
                   priority:(MPE_NetWorkPriority)priority
                    success:(void (^)(MPURLSessionTask *operation, id responseObject))success
                    failure:(void (^)(MPURLSessionTask *operation, NSError *error))failure
                  noNetWork:(MPHNoNetWorkBaseBlock)noNetWork
                     cached:(void (^)(NSDictionary *cachedObject))cached
{
    
    /**
     *  公共参数，经过条件过滤
     */
    NSString *strURL = URLString?:_strURL;
    NSDictionary *dictParams = parameters?:_dictParams;
    
    /**
     *  设置公共参数
     */
    self.mdictParams2Send = [[self setStaticCommentHTTPBody] mutableCopy];
    
    /**
     * 设置特殊公共参数
     */
    [self setcommentParamInBodySpecial];
    
    /**
     * 拼接业务参数
     */
    [self.mdictParams2Send setValuesForKeysWithDictionary:dictParams];
  
    
    /**
     *  原生框架执行请求
     */
    void (^block4Success)(MPURLSessionTask * operation, id responseObject) = ^(MPURLSessionTask * operation, id responseObject)
    {
        @synchronized(self)
        {
            [[MPBNetWorkBase allTasks] removeObject:operation];
        }
        
        void (^successTemp)(MPURLSessionTask *operation, id responseObject) = success;
        if (successTemp)
        {
            successTemp(operation, responseObject);
        }
        
        [self sendLogToServer:nil response:operation.response responseObject:nil dataTask:operation error:nil method:MPE_GET isCatche:NO isSend:YES];
        
    };
    
    __block MPURLSessionTask *operation = nil;
    NSMutableURLRequest *request = [self getSendHttpRequestByMentod:MPE_GET
                                                              param:self.mdictParams2Send
                                                               path:strURL
                                            afhttpRequestSerializer:self.httpMrg.requestSerializer
                                                            baseURL:self.httpMrg.baseURL];
    /**
     * 设置特殊请求头
     */
    [self setHTTPHeadersForSpecial:request];
    [self setChangeCommentHTTPHeadersWithRequest:request];
    
    /**
     * 设置特殊超时时间
     */
    if (_timeoutInterval >0)
    {
        request.timeoutInterval = _timeoutInterval;
    }
    
    /**
     *  加签验证
     */
    [self addSignCodeWithRequest:request param:self.mdictParams2Send];
    
    /**
     加密
     */
    
    if (isEncrypt)
    {
        [self addEncryptCodeWithRequest:request param:self.mdictParams2Send];
    }
    
    [self sendLogToServer:request
                 response:nil
           responseObject:nil
                 dataTask:nil
                    error:nil
                   method:MPE_GET
                 isCatche:NO
                   isSend:NO];
    
    /// 如果有缓存，从缓存中取
    void (^cachedTemp)(NSDictionary *cachedObject) = cached;
    if (cachedTemp)
    {
        [self getCacteDataWithRequest:request
                               method:MPE_GET
                           catcheData:^(id responseObject)
         {
             if (cachedTemp)
             {
                 cachedTemp(responseObject);
             }
         }];
    }
    
    /**
     *  检查网络
     */
    if (![[self class] hasNetWork:isShowNoNetAlert noNetBlock:noNetWork?noNetWork:self.noNetWorkInBaseBlock])
    {
        return nil;
    }
    
    
    void (^block4Failure)(MPURLSessionTask * operation, NSError * error) = ^(MPURLSessionTask * operation, NSError * error)
    {
        @synchronized(self)
        {
            [[MPBNetWorkBase allTasks] removeObject:operation];
        }
        
        void (^failureTemp)(MPURLSessionTask *operation, NSError *error) = failure;
        if (failureTemp)
        {
            failureTemp(operation, error);
        }
        
        [self sendLogToServer:nil
                         response:operation.response
                   responseObject:nil
                         dataTask:operation
                            error:nil
                           method:MPE_GET
                         isCatche:NO
                           isSend:YES];
        
    };
    
    
    operation = [_httpMrg dataTaskWithRequest:request
                               uploadProgress:nil
                             downloadProgress:nil
                            completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error)
                 {
                     if(error)
                     {
                         block4Failure(operation,error);
                     }
                     else
                     {
                         block4Success(operation,responseObject);
                     }
                 }];
    
//    operation.priority = MPDNetWorkPriority(priority);
    [operation setResponseType:_enumResponseType];
    [operation setOldApi:self.oldApi];
    [operation setRespEdsType:self.responseSecType];
    
    if (operation)
    {
        [[[self class] allTasks] addObject:operation];
    }
    
    [operation resume];
    
    
    return operation;
}

- (MPURLSessionTask *)__post:(NSString *)URLString
                  parameters:(id)parameters
            isShowNoNetAlert:(BOOL)isShowNoNetAlert
                   isEncrypt:(BOOL)isEncrypt
                    priority:(MPE_NetWorkPriority)priority
                     success:(void (^)(MPURLSessionTask *operation, id responseObject))success
                     failure:(void (^)(MPURLSessionTask *operation, NSError *error))failure
                   noNetWork:(MPHNoNetWorkBaseBlock)noNetWork
                      cached:(void (^)(NSDictionary *cachedObject))cached
{
    /**
     *  公共参数，经过条件过滤
     */
    NSString *strURL = URLString?:_strURL;
    NSDictionary *dictParams = parameters?:_dictParams;
    
    /**
     *  设置body公共参数
     */
    self.mdictParams2Send = [[self setStaticCommentHTTPBody] mutableCopy];
    
    /**
     * 设置body特殊公共参数
     */
    [self setcommentParamInBodySpecial];
    
    /**
     * 拼接业务参数
     */
    
    [self.mdictParams2Send setValuesForKeysWithDictionary:dictParams];

    
    __block MPURLSessionTask *operation = nil;
    NSMutableURLRequest *request = [self getSendHttpRequestByMentod:MPE_POST
                                                              param:self.mdictParams2Send
                                                               path:strURL
                                            afhttpRequestSerializer:self.httpMrg.requestSerializer
                                                            baseURL:self.httpMrg.baseURL];
    /**
     * 设置header特殊请求参数
     */
    [self setHTTPHeadersForSpecial:request];
    [self setChangeCommentHTTPHeadersWithRequest:request];

    /**
     * 设置特殊超时时间
     */
    if (_timeoutInterval >0)
    {
        request.timeoutInterval = _timeoutInterval;
    }
    
    /**
     *  加签验证
     */
    [self addSignCodeWithRequest:request param:self.mdictParams2Send];
    
    /**
     加密
     */
    
    if (isEncrypt)
    {
        [self addEncryptCodeWithRequest:request param:self.mdictParams2Send];
    }
    
    [self sendLogToServer:request response:nil responseObject:nil dataTask:nil error:nil method:MPE_POST isCatche:NO isSend:NO];
    
    /// 如果有缓存，从缓存中取
    void (^cachedTemp)(NSDictionary *cachedObject) = cached;
    
    if (cachedTemp)
    {
        [self getCacteDataWithRequest:request
                               method:MPE_POST
                           catcheData:^(id responseObject)
         {
             if (cachedTemp)
             {
                 cachedTemp(responseObject);
             }
         }];
    }
    
    /**
     *  检查网络
     */
    if (![[self class] hasNetWork:isShowNoNetAlert noNetBlock:noNetWork?noNetWork:self.noNetWorkInBaseBlock])
    {
        return nil;
    }

        
    /**
     *  原生框架执行请求
     */
    void (^block4Success)(MPURLSessionTask * operation, id responseObject) = ^(MPURLSessionTask * operation, id responseObject)
    {
        @synchronized(self)
        {
            [[MPBNetWorkBase allTasks] removeObject:operation];
        }
        void (^successTemp)(MPURLSessionTask *operation, id responseObject) = success;
        if (successTemp)
        {
            successTemp(operation, responseObject);
        }
        
        [self sendLogToServer:nil
                     response:operation.response
               responseObject:nil
                     dataTask:operation
                        error:nil
                       method:MPE_POST
                     isCatche:NO
                       isSend:YES];
        
    };
    
    void (^block4Failure)(MPURLSessionTask * operation, NSError * error) = ^(MPURLSessionTask * operation, NSError * error)
    {
        @synchronized(self)
        {
            [[MPBNetWorkBase allTasks] removeObject:operation];
        }
        void (^failureTemp)(MPURLSessionTask *operation, NSError *error) = failure;
        if (failureTemp)
        {
            failureTemp(operation, error);
        }
        
        [self sendLogToServer:nil
                     response:operation.response
               responseObject:nil
                     dataTask:operation
                        error:nil
                       method:MPE_POST
                     isCatche:NO
                       isSend:YES];
        
        [self sendLogToServer:nil
                     response:operation.response
               responseObject:nil
                     dataTask:operation
                        error:error
                       method:MPE_POST
                     isCatche:NO
                       isSend:YES];
    };
    
    operation = [_httpMrg dataTaskWithRequest:request
                               uploadProgress:nil
                             downloadProgress:nil
                            completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error)
                 {
                     NSLog(@"base回来了");
                     if(error)
                     {
                         block4Failure(operation,error);
                     }
                     else
                     {
                         block4Success(operation,responseObject);
                     }
                 }];
    
//    operation.priority = MPDNetWorkPriority(priority);
    
    [operation setResponseType:_enumResponseType];
    [operation setOldApi:self.oldApi];
    [operation setRespEdsType:self.responseSecType];
    
    if (operation)
    {
        [[[self class] allTasks] addObject:operation];
    }
    
    [operation resume];
    
    return operation;
}


/***************************************************************************************************
 *  异步请求，上传文件
 ***************************************************************************************************/

- (MPURLSessionTask *)POST:(NSString *)URLString
                parameters:(id)parameters
          isShowNoNetAlert:(BOOL)isShowNoNetAlert
                 isEncrypt:(BOOL)isEncrypt
                  priority:(MPE_NetWorkPriority)priority
 constructingBodyWithBlock:(void (^)(id<AFMultipartFormData>))block
                   success:(void (^)(MPURLSessionTask *, id))success
                   failure:(void (^)(MPURLSessionTask *, NSError *))failure
{
    
    /**
     *  检查网络
     */
    if (![[self class] hasNetWork:isShowNoNetAlert noNetBlock:self.noNetWorkInBaseBlock])
    {
        return nil;
    }
    
    /**
     *  公共参数，经过条件过滤
     */
    NSString *strURL = URLString?:_strURL;
    NSDictionary *dictParams = parameters?:_dictParams;
    
    /**
     *  设置body公共参数
     */
    self.mdictParams2Send = [[self setStaticCommentHTTPBody] mutableCopy];
    
    /**
     * 设置特殊公共参数
     */
    [self setcommentParamInBodySpecial];
    
    /**
     * 拼接业务参数
     */
    
    [self.mdictParams2Send setValuesForKeysWithDictionary:dictParams];

    NSMutableURLRequest *request = [self.httpMrg.requestSerializer
                                    multipartFormRequestWithMethod:@"POST"
                                    URLString:[NSString stringWithFormat:@"%@%@",[self _baseurl],strURL]
                                    parameters:parameters
                                    constructingBodyWithBlock:block
                                    error:nil];

    
    
    /**
     * 设置特殊请求头
     */
    [self setHTTPHeadersForSpecial:request];
    [self setChangeCommentHTTPHeadersWithRequest:request];
    
    /**
     * 设置特殊超时时间
     */
    if (_timeoutInterval >0)
    {
        request.timeoutInterval = _timeoutInterval;
    }

    
    /**
     *  加签验证，上传请求，将加签字段放在url后面
     */
    [self addSignCodeWithRequest:request param:self.mdictParams2Send];

    /**
     加密
     */
    
    if (isEncrypt)
    {
        [self addEncryptCodeWithRequest:request param:self.mdictParams2Send];
    }
    
    /**
     *  原生框架执行请求
     */
    void (^block4Success)(MPURLSessionTask * operation, id responseObject) = ^(MPURLSessionTask * operation, id responseObject)
    {
        @synchronized(self)
        {
            [[MPBNetWorkBase allTasks] removeObject:operation];
        }
        
        void (^successTemp)(MPURLSessionTask *, id) = success;
        if (successTemp)
        {
            successTemp(operation, responseObject);
        }
    };
    void (^block4Failure)(MPURLSessionTask * operation, NSError * error) = ^(MPURLSessionTask * operation, NSError * error)
    {
        @synchronized(self)
        {
            [[MPBNetWorkBase allTasks] removeObject:operation];
        }
        
        void (^failureTemp)(MPURLSessionTask *, NSError *) = failure;
        failureTemp(operation, error);
    };
        
    __block MPURLSessionTask *operation =
    [self.httpMrg uploadTaskWithStreamedRequest:request
                               progress:nil
                      completionHandler:^(NSURLResponse *_Nonnull response,
                                          id _Nullable responseObject,
                                          NSError *_Nullable error) {
                          if (error) {
                              if (block4Failure) {
                                  block4Failure(operation, error);
                              }
                          } else {
                              if (block4Success) {
                                  block4Success(operation, responseObject);
                              }
                          }
                          
                      }];
    
    [operation setResponseType:_enumResponseType];
    [operation setOldApi:self.oldApi];
    [operation setRespEdsType:self.responseSecType];
    if (operation)
    {
        [[[self class] allTasks] addObject:operation];
    }
    
    [operation resume];

        
    return operation;
}

- (MPURLSessionTask *)POST:(NSString *)URLString
                parameters:(id)parameters
          isShowNoNetAlert:(BOOL)isShowNoNetAlert
                 isEncrypt:(BOOL)isEncrypt
                  priority:(MPE_NetWorkPriority)priority
                  fromData:(nullable NSData *)bodyData
                   success:(void (^)(MPURLSessionTask *operation, id responseObject))success
                   failure:(void (^)(MPURLSessionTask *operation, NSError *error))failure
{
    /**
     *  检查网络
     */
    if (![[self class] hasNetWork:isShowNoNetAlert noNetBlock:self.noNetWorkInBaseBlock])
    {
        return nil;
    }
    
    /**
     *  公共参数，经过条件过滤
     */
    NSString *strURL = URLString?:_strURL;
    NSDictionary *dictParams = parameters?:_dictParams;
    
    /**
     *  设置body公共参数
     */
    self.mdictParams2Send = [[self setStaticCommentHTTPBody] mutableCopy];
    
    /**
     * 设置特殊公共参数
     */
    [self setcommentParamInBodySpecial];
    
    /**
     * 拼接业务参数
     */
    
    [self.mdictParams2Send setValuesForKeysWithDictionary:dictParams];
    
    
    NSMutableURLRequest *request = [self getSendHttpRequestByMentod:MPE_POST
                                                              param:self.mdictParams2Send
                                                               path:strURL
                                            afhttpRequestSerializer:self.httpMrg.requestSerializer
                                                            baseURL:self.httpMrg.baseURL];
    /**
     * 设置特殊请求头
     */
    [self setHTTPHeadersForSpecial:request];
    [self setChangeCommentHTTPHeadersWithRequest:request];
    
    /**
     * 设置特殊超时时间
     */
    if (_timeoutInterval >0)
    {
        request.timeoutInterval = _timeoutInterval;
    }
    
    
    /**
     *  加签验证，上传请求，将加签字段放在url后面
     */
    [self addSignCodeWithRequest:request param:self.mdictParams2Send];
    
    /**
     加密
     */
    
//    if (isEncrypt)
//    {
//        [self addEncryptCodeWithRequest:request param:self.mdictParams2Send];
//    }
    
    /**
     *  原生框架执行请求
     */
    void (^block4Success)(MPURLSessionTask * operation, id responseObject) = ^(MPURLSessionTask * operation, id responseObject)
    {
        @synchronized(self)
        {
            [[MPBNetWorkBase allTasks] removeObject:operation];
        }
        
        void (^successTemp)(MPURLSessionTask *, id) = success;
        if (successTemp)
        {
            successTemp(operation, responseObject);
        }
    };
    void (^block4Failure)(MPURLSessionTask * operation, NSError * error) = ^(MPURLSessionTask * operation, NSError * error)
    {
        @synchronized(self)
        {
            [[MPBNetWorkBase allTasks] removeObject:operation];
        }
        
        void (^failureTemp)(MPURLSessionTask *, NSError *) = failure;
        failureTemp(operation, error);
    };
    
    MPURLSessionTask *operation = [_httpMrg uploadTaskWithRequest:request fromData:bodyData progress:^(NSProgress * _Nonnull uploadProgress)
    {
        
    } completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error)
    {
        if (error)
        {
            block4Failure(operation, error);
        }
        else
        {
            block4Success(operation, responseObject);
        }
    }];
    
    
    [operation setResponseType:_enumResponseType];
    [operation setOldApi:self.oldApi];
    [operation setRespEdsType:self.responseSecType];
    if (operation)
    {
        [[[self class] allTasks] addObject:operation];
    }
    
    [operation resume];
    
    return operation;
}



/***************************************************************************************************
 *  同步请求
 ***************************************************************************************************/

- (id)netWorkSyncWithURL:(NSString *)URLString
                  params:(NSDictionary *)parameters
        isShowNoNetAlert:(BOOL)isShowNoNetAlert
               isEncrypt:(BOOL)isEncrypt
                priority:(MPE_NetWorkPriority)priority
                  cached:(void (^)(NSDictionary *cachedObject))cached
{
    return [self netWorkSyncWithMethod:@"POST"
                                   URL:URLString
                                params:parameters
                      isShowNoNetAlert:isShowNoNetAlert
                             isEncrypt:isEncrypt
                              priority:priority
                               success:nil
                               failure:nil
                                cached:cached];
}

- (id)netWorkSyncWithURL:(NSString *)URLString
                  params:(NSDictionary *)parameters
        isShowNoNetAlert:(BOOL)isShowNoNetAlert
               isEncrypt:(BOOL)isEncrypt
                priority:(MPE_NetWorkPriority)priority
                 success:(void (^)(id responseObject))success
                 failure:(void (^)(id responseObject))failure
                  cached:(void (^)(NSDictionary *cachedObject))cached
{
    
    return [self netWorkSyncWithMethod:@"POST"
                                   URL:URLString
                                params:parameters
                      isShowNoNetAlert:isShowNoNetAlert
                             isEncrypt:isEncrypt
                              priority:priority
                               success:success
                               failure:failure
                                cached:cached];
    
}

- (id)netWorkSyncWithMethod:(NSString *)method
                        URL:(NSString *)URLString
                     params:(NSDictionary *)parameters
           isShowNoNetAlert:(BOOL)isShowNoNetAlert
                  isEncrypt:(BOOL)isEncrypt
                   priority:(MPE_NetWorkPriority)priority
                    success:(void (^)(id responseObject))success
                    failure:(void (^)(id responseObject))failure
                     cached:(void (^)(NSDictionary *cachedObject))cached
{
    
    /**
     *  公共参数，经过条件过滤
     */
    NSString *strURL = URLString?:_strURL;
    NSDictionary *dictParams = parameters?:_dictParams;
    
    /**
     *  设置body公共参数
     */
    self.mdictParams2Send = [[self setStaticCommentHTTPBody] mutableCopy];
    
    /**
     * 设置特殊公共参数
     */
    [self setcommentParamInBodySpecial];
    
    /**
     * 拼接业务参数
     */
    
        [self.mdictParams2Send setValuesForKeysWithDictionary:dictParams];

    
    NSMutableURLRequest *request = [self getSendHttpRequestByMentod:MPE_POST
                                                              param:self.mdictParams2Send
                                                               path:strURL
                                            afhttpRequestSerializer:self.httpMrg.requestSerializer
                                                            baseURL:self.httpMrg.baseURL];
    /**
     * 设置特殊请求头
     */
    [self setHTTPHeadersForSpecial:request];
    [self setChangeCommentHTTPHeadersWithRequest:request];

    /**
     * 设置特殊超时时间
     */
    if (_timeoutInterval >0)
    {
        request.timeoutInterval = _timeoutInterval;
    }
    
    /**
     *  加签验证
     */
    [self addSignCodeWithRequest:request param:self.mdictParams2Send];
    
    /**
     加密
     */
    
    if (isEncrypt)
    {
        [self addEncryptCodeWithRequest:request param:self.mdictParams2Send];
    }
    
    /// 如果有缓存，从缓存中取
    void (^cachedTemp)(NSDictionary *cachedObject) = cached;
    if (cachedTemp)
    {
        [self getCacteDataWithRequest:request
                               method:[method isEqualToString:@"GET"] ? MPE_GET:MPE_POST
                           catcheData:^(id responseObject)
         {
             if (cachedTemp)
             {
                 cachedTemp(responseObject);
             }
         }];
    }
    
    /**
     *  检查网络
     */
    if (![[self class] hasNetWork:isShowNoNetAlert noNetBlock:self.noNetWorkInBaseBlock])
    {
        return nil;
    }
    
    void (^failureTemp)(id responseObject) = failure;
    void (^successTemp)(id responseObject) = success;
    
    /**
     *  执行同步请求
     */
    NSURLResponse *response = nil;
    NSError *error = nil;
    NSData *dataResponse = [NSURLConnection sendSynchronousRequest:request
                                                 returningResponse:&response
                                                             error:&error];
    
    if (error)
    {
        
        if (failureTemp)
        {
            failureTemp(nil);
        }
        return nil;
    }
    
    id jsonResult;
    if (dataResponse)
    {
        AFHTTPResponseSerializer *serializer = [self getResponseSerializerWithResponseType:_enumResponseType];
        NSError *errorDecode;
        jsonResult = [serializer responseObjectForResponse:response data:dataResponse error:&errorDecode];
        
    }
    if (error)
    {
        if (failureTemp)
        {
            failureTemp(jsonResult);
        }
        return nil;
    }
    
    if (successTemp)
    {
        successTemp(jsonResult);
    }
    
    return jsonResult;
}

- (void)dealloc
{
    NSLog(@"======>>> %s", __func__);
}

#pragma mark -- ***********************************需要扩展的方法**********************************

- (AFHTTPResponseSerializer *)getResponseSerializerWithResponseType:(MPE_NetResponseType)responseType
{
    AFHTTPResponseSerializer *responseSerializer = nil;
    switch (responseType)
    {
        case MPE_NetResponseType_Json:
            
            responseSerializer = [AFJSONResponseSerializer serializer];
            responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",
                                                         @"application/x-www-form-urlencoded",
                                                         @"text/html",@"text/json",
                                                         @"text/javascript",
                                                         @"text/plain",
                                                         nil];
            break;
        case MPE_NetResponseType_Data:
        {
            responseSerializer = [AFHTTPResponseSerializer serializer];
            responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",
                                                         @"application/x-www-form-urlencoded",
                                                         @"text/html",@"text/json",
                                                         @"text/javascript",
                                                         @"text/plain",
                                                         nil];
        }
            break;
        default:
        {
            responseSerializer = [AFJSONResponseSerializer serializer];
            responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",
                                                         @"application/x-www-form-urlencoded",
                                                         @"text/html",@"text/json",
                                                         @"text/javascript",
                                                         @"text/plain",
                                                         nil];
        }
            break;
    }
    
    return responseSerializer;
}

/**
 *
 *  设置不变的header参数  初始化requestSerializer时就可以设置
 */
- (void)setStatiCcommentHTTPHeaders
{
    
}


/**
 设置可变的header参数
 
 @param request 请求对象。每次都要去设置对应的header参数
 */
- (void)setChangeCommentHTTPHeadersWithRequest:(NSMutableURLRequest *)request
{
    
}

/**
 设置特殊的请求头
 */
- (void)setHTTPHeadersForSpecial:(NSMutableURLRequest *)request
{
    for (id key in self.dicParamCommonHeader)
    {
        id value = [self.dicParamCommonHeader objectForKey:key];
        if ([value isKindOfClass:[NSNumber class]])
        {
            value = [((NSNumber *)value) stringValue];
        }
        [request setValue:value forHTTPHeaderField:key];
    }
}

/**
 设置body固定的公共参数
 
 @return body公共参数
 */
- (NSMutableDictionary *)setStaticCommentHTTPBody
{
    NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:0];
    
    return dict;
}


/**
 覆盖body固定公共参数中特殊的参数
 */
- (void)setcommentParamInBodySpecial
{
    /// 替换特殊的bodyCommentParam
    if (self.dicParamCommonBody)
    {
        [self.mdictParams2Send setValuesForKeysWithDictionary:self.dicParamCommonBody];
    }
}


/**
 创建request请求对象
 
 @param method <#method description#>
 @param parameters <#parameters description#>
 @param path <#path description#>
 @param requestSerializer <#requestSerializer description#>
 @param baseURL <#baseURL description#>
 @return <#return value description#>
 */
- (NSMutableURLRequest *)getSendHttpRequestByMentod:(MPE_NetMethod)method
                                              param:(NSDictionary *)parameters
                                               path:(NSString *)path
                            afhttpRequestSerializer:(AFHTTPRequestSerializer *)requestSerializer
                                            baseURL:(NSURL *)baseURL
{
    NSMutableURLRequest *request = [_httpMrg.requestSerializer
                                    requestWithMethod:(method == MPE_POST ? @"POST" : @"GET")
                                    URLString:path
                                    parameters:parameters
                                    error:nil];
    
    return request;
}

/**
 签名
 
 @param request <#request description#>
 @param parameters <#parameters description#>
 */
- (void)addSignCodeWithRequest:(NSMutableURLRequest *)request param:(NSDictionary *)parameters
{
    
}

/**
 加密
 
 @param request <#request description#>
 @param parameters <#parameters description#>
 */
- (void)addEncryptCodeWithRequest:(NSMutableURLRequest *)request param:(NSDictionary *)parameters
{
    
}



/**
 获取缓存数据
 
 @param request <#request description#>
 @param method <#method description#>
 @param catcheData <#catcheData description#>
 */
- (void)getCacteDataWithRequest:(NSURLRequest *)request
                         method:(MPE_NetMethod)method
                     catcheData:(void (^)(id responseObject))catcheData
{
    catcheData(nil);
}

- (void)sendLogToServer:(NSURLRequest *)request
               response:(NSURLResponse *)response
         responseObject:(id)responseObject
               dataTask:(NSURLSessionTask *)dataTask
                  error:(NSError *)error
                 method:(MPE_NetMethod)method
               isCatche:(BOOL)isCatche
                 isSend:(BOOL)isSend
{
    
}

+ (BOOL)hasNetWork:(BOOL)isShow noNetBlock:(BOOL(^)())noNetBlock
{
    return YES;
}

+ (MPE_NetWorkState)checkState4Result:(id)idResult
                                 task:(MPURLSessionTask *)task
         isShowToastView4NetWorkState:(BOOL)isShowToastView4NetWorkState
                               cached:(void (^)(NSDictionary *cachedObject))cached
                  sessionTimeoutBlock:(void (^)(MPE_NetWorkSessionState state))sessionTimeoutBlock
{
    if (idResult == nil)
    {
        return MPE_NetWorkState_Fail;
    }
    else
    {
        return MPE_NetWorkState_Successs;
    }
}

+ (id)resetResponse:(id)resp
{
    return resp;
}

- (NSString *)_baseurl
{
    return @"";
}

#pragma mark -- ********************************工具类方法*****************************************

- (void)setRequestURL:(NSString *)strURL
{
    _strURL = [strURL copy];
}

- (void)setOverloadParameters:(NSDictionary *)dictParams
{
    _dictParams = dictParams;
}

/// 设置header公共参数
- (void)setOverloadHeaderCommentParameters:(NSDictionary *)dicHeaderParams
{
    _dicParamCommonHeader = dicHeaderParams;
}
/// 设置body公共参数
- (void)setOverloadBodyCommentParameters:(NSDictionary *)dicBodyParams
{
    _dicParamCommonBody = dicBodyParams;
}

- (void)setResponseType:(MPE_NetResponseType)type
{
    if (_enumResponseType == type)
    {
        return;
    }
    
    _enumResponseType = type;
    
    _httpMrg.responseSerializer = [self getResponseSerializerWithResponseType:type];
}

- (void)setTimeoutInterval:(CGFloat)timeoutInterval
{
    if (timeoutInterval >0)
    {
        _timeoutInterval = timeoutInterval;
    }
}

- (NSMutableDictionary *)mdictParams2Send
{
    if (!_mdictParams2Send)
    {
        _mdictParams2Send = [NSMutableDictionary dictionaryWithCapacity:0];
    }
    
    return _mdictParams2Send;
}

+ (Class)getSubNetBaseClass
{
    return [MPBNetWorkBase class];
}

@end
